// var a =1



// function bar(){
//     var a =2
   
    // function foo(){
    //     console.log(this.a);
        
    // }

//     return foo;
// }

// const baz = bar();

// baz(); // 2

// var a=1

let obj = {
    a:2,
    fn:foo
}

// let obj2 = {
//     a:3,
//     fm:obj
// }

// function foo(){
//     console.log(this.a);
// }
// obj2.fm.fn()



// foo(2,5)

// obj.call(obj,2,5)//会报错,obj.call is nor a function
// foo.apply(obj,[2,5]);
// foo.apply(obj)
// const bar = foo.bind(obj) //bind返回一个函数，得被调用才能用
// bar() // 
function foo(x,y){
    console.log(this.a,x+y);
    return 'hello'
    
}
foo.call(obj,2,5)
Function.prototype.mycall = function(context,...args){
    if(typeof(this) !=='function'){
            throw new TypeError('this is nor a function')
        } 

    context = context || window;
    const key = Symbol('fn')
    context[key] = this;
    const res= context[Symbol('fn')](...args)
    delete context[Symbol('fn')]
    return res


}

Function.prototype.myapply = function(context,args){
    if(typeof(this) !=='function'){
            throw new TypeError('this is nor a function')
        } 

    context = context || window;
    const key = Symbol('fn')
    context[key] = this;
    const res= context[key](...args)
    delete context[key]
    return res

}

Function.prototype.mybind = function(context,...args){
    if(typeof(this) !=='function'){
            throw new TypeError('this is nor a function')                                                                                                       
        } 

    context = context || window;
    const self = this
    
    return function Fn(...arg){
        if(this.__proto__ === Fn.prototype){//被new调用，返回foo实例
         return new self(...args,...arg)
        }else{
         return   self.apply(context,[...args,...arg])
        }
       
    }
    

}


const res= foo.myapply(obj,[2,5])
console.log(res);





